<?php
// +----------------------------------------------------------------------
// | najing [ 通用后台管理系统 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2020 http://www.najingquan.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: 救火队队长
// +----------------------------------------------------------------------

namespace server;

require __DIR__ . '/../vendor/autoload.php';

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Config;

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Exchange\AMQPExchangeType;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Wire\AMQPTable;
use \app\index\controller\Mq;
use \app\index\service\ConfigService;
use \app\index\service\MessageService;

/**
 * 概要描述：WebSocket服务器
 * @author: 救火队队长
 * @since: 2020-05-23 22:45
 */
class WebSocketServer
{
    protected $serv = null;       //Swoole\Server对象
    protected $host = '0.0.0.0'; //监听对应外网的IP 0.0.0.0监听所有ip
    protected $port = 9604;      //监听端口号

    public function __construct()
    {
        //创建websocket服务器对象，监听0.0.0.0:9604端口
        $this->serv = new \Swoole\Websocket\Server($this->host, $this->port);

        //设置参数
        //如果业务代码是全异步 IO 的，worker_num设置为 CPU 核数的 1-4 倍最合理
        //如果业务代码为同步 IO，worker_num需要根据请求响应时间和系统负载来调整，例如：100-500
        //假设每个进程占用 40M 内存，100 个进程就需要占用 4G 内存
        $this->serv->set(array(
            'worker_num' => 4,         //设置启动的worker进程数。【默认值：CPU 核数】
            'max_request' => 10000,    //设置每个worker进程的最大任务数。【默认值：0 即不会退出进程】
            //'daemonize' => 0,          //开启守护进程化【默认值：0】
            'pid_file'              => '/www/wwwroot/ex.saruri.cn/runtime/'. 'swooleSigle.pid',
            'log_file'              => '/www/wwwroot/ex.saruri.cn/runtime/' . 'swooleSigle.log',
            'daemonize'             => false,
            
        ));

        //监听WebSocket连接打开事件
        $this->serv->on('open', function ($serv, $req) {
            echo "connection open: {$req->fd}" . PHP_EOL;
        });

        //监听WebSocket消息事件
        //客户端向服务器端发送信息时，服务器端触发 onMessage 事件回调
        //服务器端可以调用 $server->push() 向某个客户端（使用 $fd 标识符）发送消息，长度最大不得超过 2M
        $this->serv->on('message', function ($serv, $frame) {

            //for ($i=0; $i < 100; $i++) {
                
            //Mq::instance()->send();
            //$this->mq= new \app\index\controller\Mq();
            //var_dump(Mq);
            //$mqResult=
            $this->sendMq($frame);
            //echo $mqResult."Message: 9999{$frame->data}". PHP_EOL;
            //$this->serv->push($frame->fd, "server: {$frame->data}");
            //$this->serv->push($frame->fd, "server: {发送ok}");
            //}
        });

        //监听WebSocket连接关闭事件
        $this->serv->on('close', function ($serv, $fd) {
            echo "connection close: {$fd}". PHP_EOL;
        });

        //启动服务
        $this->serv->start();
    }

    
    /*
    *  @desc      方法说明
    *  @author    saruri <saruri@163.com>
    *  @date      2020/08/01 18:05:35
    */
    public function conn()
    {
        //do somehing
        // halt($this->MqConfig);
        //echo phpinfo();
        // exit();
        $this->MqConfig= [
        // 默认缓存驱动
        'ip' => '127.0.0.1',
        'user'=>'saruri',
        'pwd'=>'sarurifanziping3389@',
        'port'=>5672,
        'vhost'=>'/'
    ];
    
        $connection= new AMQPStreamConnection($this->MqConfig['ip'], $this->MqConfig['port'], $this->MqConfig['user'], $this->MqConfig['pwd'], $this->MqConfig['vhost']);
        return $connection;
    }



    /*
    *  @desc      发送队列
    *  @author    saruri <saruri@163.com>
    *  @date      2020/08/01 18:02:52
    */
    public function sendMq($frame)
    {
        //队列名  消息队列载体，每个消息都会被投入到一个或多个队列。
        $queue = 'hello';
        $routing =$queue;
        //建立连接
        $connection = self::conn();//new AMQPStreamConnection('127.0.0.1', 5672, 'zq', '123456', '/');
        //获取信道
        $channel = $connection->channel();

        //声明创建队列
        $channel->queue_declare($queue, false, false, false, false);

        //$frame->fd, "server: {$frame->data}"
        
        //循环分页
        //返回数组 arr['page']
        //返回数组 arr['messageBody']
        $arr=[];
        $arr=MessageService::instance()->getMessage($frame);
        //echo  "<<<分页TEST:". $arr['test']."\n";
        // var_dump($arr);
        foreach ($arr['page'] as $key => $value) {

            $arr['messageBody']['tab']=$arr['tab'];
            $arr['messageBody']['page']['num']=$key+1;
            $arr['messageBody']['page']['start']=$value['start'];
            $arr['messageBody']['page']['end']=$value['end'];
            $arr['messageBody']['server']=$this->serv;
            $messageBody=json_encode($arr['messageBody']);

            $message = new AMQPMessage($messageBody, array('content_type' => 'text/plain', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT));
            //     //发送消息
            $channel->basic_publish($message, '', $routing);

            echo ">>>".$frame->fd."<<<分页Send Message:". $key.'------>'.time()."TAB:".$arr['tab']."\n";
            
            $jsonMessage=json_encode($arr);
            unset($arr['messageBody']['server']);
            $arr['event']='sendMqSuccess';
            $arr['fd']=$frame->fd;

            $this->serv->push($frame->fd, "message: $jsonMessage");
            sleep(1);
        }

       

        //for ($i=0; $i < 10; ++$i) {
            //sleep(1);//休眠1秒
            //消息内容
            //$messageBody = 'FRAMEID->'.$frame->fd."saruri hello Now Time:".date("h:i:s");
            //$messageBody =MessageService::instance()->build($frame);//构建

            //将我们需要的消息标记为持久化 - 通过设置AMQPMessage的参数delivery_mode = AMQPMessage::DELIVERY_MODE_PERSISTENT
            //$message = new AMQPMessage($messageBody, array('content_type' => 'text/plain', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT));
            //发送消息
            //$channel->basic_publish($message, '', $routing);
            //echo ">>>".$frame->fd."<<<Send Message:". $i."\n";
        //}

        //关闭信道
        $channel->close();
        //关闭连接
        $connection->close();
        return 'Send Success';
    }
}

$webSocketServer = new WebSocketServer();
